package org.mozhu.mboot.core.data;

import org.mozhu.mboot.core.data.filter.Operator;
import org.mozhu.mboot.core.data.filter.SearchFilter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 查询条件接口
 * </p>
 */
public abstract class Searchable {

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable() {
        return new SearchRequest();
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Pageable page) {
        return new SearchRequest(page);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Sort sort) {
        return new SearchRequest(sort);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Pageable page, final Sort sort) {
        return new SearchRequest(page, sort);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Map<String, Object> searchParams) {
        return new SearchRequest(searchParams);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Map<String, Object> searchParams, final Pageable page) {
        return new SearchRequest(searchParams, page);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Map<String, Object> searchParams, final Sort sort) {
        return new SearchRequest(searchParams, sort);
    }

    /**
     * 创建一个新的查询
     *
     * @return
     */
    public static Searchable newSearchable(final Map<String, Object> searchParams, final Pageable page, final Sort sort) {
        return new SearchRequest(searchParams, page, sort);
    }

    /**
     * 添加过滤条件 如key="eq_parent.id" value = 1
     *
     * @param key   如 eq_parent.id
     * @param value
     * @return
     */
    public abstract Searchable addSearchParam(final String key, final Object value);

    /**
     * 添加一组查询参数
     *
     * @param searchParams
     * @return
     */
    public abstract Searchable addSearchParams(final Map<String, Object> searchParams);

    /**
     * 添加过滤条件
     *
     * @param propertyName 查询的属性名
     * @param operator     操作运算符
     * @param value        值
     */
    public abstract Searchable addSearchFilter(final String propertyName, final Operator operator, final Object value);

    public abstract Searchable addSearchFilter(final String propertyName, final Operator operator, final Object[] value);

    public abstract Searchable addSearchFilter(final List<String> propertyNames, final Operator operator, final Object value);

    public abstract Searchable addSearchFilter(final SearchFilter searchFilter);

    /**
     * 添加多个and连接的过滤条件
     *
     * @param searchFilters
     * @return
     */
    public abstract Searchable addSearchFilters(final Collection<? extends SearchFilter> searchFilters);

    /**
     * 添加多个or连接的过滤条件
     */
    public abstract Searchable or(final SearchFilter... searchFilters);

    /**
     * 添加多个and连接的过滤条件
     */
    public abstract Searchable and(final SearchFilter... searchFilters);

    /**
     * 移除指定key的过滤条件
     *
     * @param key
     */
    public abstract Searchable removeSearchFilter(final String key);

    /**
     * 移除指定属性 和 操作符的过滤条件
     *
     * @param searchProperty
     * @param operator
     * @return
     */
    public abstract Searchable removeSearchFilter(String searchProperty, Operator operator);

    public abstract Searchable setPage(final Pageable page);

    /**
     * @param pageNumber 分页页码 索引从 0 开始
     * @param pageSize   每页大小
     * @return
     */
    public abstract Searchable setPage(final int pageNumber, final int pageSize);

    public abstract Searchable addSort(final Sort sort);

    public abstract Searchable addSort(final Sort.Direction direction, String property);

    /**
     * 获取查询过滤条件
     *
     * @return
     */
    public abstract Collection<SearchFilter> getSearchFilters();

    /**
     * 是否有查询参数
     *
     * @return
     */
    public abstract boolean hasSearchFilter();

    /**
     * 是否有排序
     *
     * @return
     */
    public abstract boolean hashSort();

    public abstract void removeSort();

    /**
     * 是否有分页
     *
     * @return
     */
    public abstract boolean hasPageable();

    public abstract void removePageable();

    /**
     * 获取分页和排序信息
     *
     * @return
     */
    public abstract Pageable getPage();

    /**
     * 获取排序信息
     *
     * @return
     */
    public abstract Sort getSort();

    /**
     * 是否包含查询键 如 like_name 包括 or 和 and的
     *
     * @param key
     * @return
     */
    public abstract boolean containsSearchKey(final String key);

    /**
     * 获取查询属性对应的值 不能获取or 或 and 的
     *
     * @param key
     * @return
     */
    public abstract <T> T getValue(final String key);

}
